package com.bdqn.qnnews.wemedia.job;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.bdqn.qnnews.common.constants.ScheduleConstants;
import com.bdqn.qnnews.schedule.api.dto.TaskDto;
import com.bdqn.qnnews.schedule.api.feign.TaskFeignClient;
import com.bdqn.qnnews.wemedia.entity.WmNews;
import com.bdqn.qnnews.wemedia.mapper.WmNewsMapper;
import com.bdqn.qnnews.wemedia.service.WmNewsAutoScanService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author xlzhang
 * @date 2024/1/17 10:30
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class WmNewsTaskJob {

    private final TaskFeignClient taskFeignClient;
    private final WmNewsAutoScanService wmNewsAutoScanService;
    private final WmNewsMapper wmNewsMapper;
    private final RedissonClient redissonClient;

    /**
     * 定时消费自媒体文章的定时任务
     * 默认每 5秒执行一次
     */
    @Scheduled(cron = "*/5 * * * * ?")
    public void pollWmNewsTask() throws InterruptedException {
        // 添加分布式锁，实现多个服务同时开启定时任务的互斥问题
        final RLock lock = redissonClient.getLock("poll-news-task-key");
        // 不写默认30秒自动释放
        // 注意这个时间必须小于定时任务间隔时间，否则定时任务会被中断
        final boolean res = lock.tryLock(0,3, TimeUnit.SECONDS);
        if (!res){
            System.out.println("获取锁失败，任务中断: " + res);
            return;
        }
        log.debug("--开始消费定时任务--");
        // 1.到延迟队列中拉取任务
        // 远程调优定时微服务执行消费功能
        List<TaskDto> taskList = taskFeignClient.pollTask(ScheduleConstants.TASK_TOPIC_NEWS_PUBLISH);
        log.debug("当前的要发布的定时任务为:{}",taskList);
        if(CollectionUtils.isNotEmpty(taskList)){
            for(TaskDto task:taskList){
                // 2.从TaskDto中取出数据转换为对象，获取文章ID
                WmNews wmNews = JSONUtil.toBean(task.getParameters(), WmNews.class);
                // 3. 根据文章id查询完整的待发布文章数据
                wmNews = wmNewsMapper.selectById(wmNews.getId());
                // 4. 发布文章
                wmNewsAutoScanService.publishApAticle(wmNews);
                log.info("文章: id={} 已经定时发布成功",wmNews.getId());
            }
        }
    }
}
